//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using System;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;

namespace EntLibContrib.Mapping.Configuration.Design
{
	/// <summary>
	/// Represents the design manager that will register the design time information for the Mapping Application Block.
	/// </summary>
	public sealed class MappingConfigurationDesignManager : ConfigurationDesignManager
	{
		#region Construction
		/// <summary>
		/// Initialize a new instance of the <see cref="MappingConfigurationDesignManager"/> class.
		/// </summary>
		public MappingConfigurationDesignManager()
		{
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Registers the mapping design manager into the environment.
		/// </summary>
		/// <param name="serviceProvider">The mechanism for retrieving a service object; that is, an object that provides custom support to other objects.</param>
		public override void Register (IServiceProvider serviceProvider)
		{
			MappingNodeMapRegistrar nodeRegistrar = new MappingNodeMapRegistrar(serviceProvider);
			nodeRegistrar.Register();
			MappingCommandRegistrar commandRegistrar = new MappingCommandRegistrar(serviceProvider);
			commandRegistrar.Register();
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Opens the mapping configuration from an application configuration file.
		/// </summary>
		/// <param name="serviceProvider">A mechanism for retrieving a service object; that is an object that provides custom support to other objects.</param>
		/// <param name="rootNode">The <see cref="ConfigurationApplicationNode"/> of the hierarchy.</param>
		/// <param name="section">The mapping configuration section or null if no section was found.</param>
		protected override void OpenCore (IServiceProvider serviceProvider, ConfigurationApplicationNode rootNode, ConfigurationSection section)
		{
			if ( null != section )
			{
				MappingSettingsNodeBuilder builder = new MappingSettingsNodeBuilder(serviceProvider, (MappingSettings)section);
				MappingSettingsNode mappingSettingsNode = builder.Build();
				SetProtectionProvider(section, mappingSettingsNode);

				rootNode.AddNode(mappingSettingsNode);
			}
		}

		/// <summary>
		/// Gets a <see cref="ConfigurationSectionInfo"/> object containing the Mapping Block's configuration information.
		/// </summary>
		/// <param name="serviceProvider">A mechanism for retrieving a service object; that is, an object that provides custom support to other objects.</param>
		/// <returns>
		/// A <see cref="ConfigurationSectionInfo"/> object containing the Mapping Block's configuration information.
		/// </returns>
		protected override ConfigurationSectionInfo GetConfigurationSectionInfo (IServiceProvider serviceProvider)
		{
			ConfigurationNode rootNode = ServiceHelper.GetCurrentRootNode(serviceProvider);
			MappingSettingsNode node = null;
			if (rootNode != null)
				node = (MappingSettingsNode)rootNode.Hierarchy.FindNodeByType(rootNode, typeof(MappingSettingsNode));

			MappingSettings mappingSettings = null;
			if ( node == null )
				mappingSettings = null;
			else
			{
				MappingSettingsBuilder builder = new MappingSettingsBuilder(serviceProvider, node);
				mappingSettings = builder.Build();
			}
			string protectionProviderName = GetProtectionProviderName(node);

			return new ConfigurationSectionInfo(node, mappingSettings, MappingSettings.SectionName, protectionProviderName);
		}
		#endregion
	}
}